// 输入框描述

import 'package:bruno/bruno.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:yt_devops/styles/styles.dart';

class YtInput extends StatefulWidget {
  // 标题宽度
  double titleWidth;

  double? height;
  // 行数
  int? maxLines;
  // 输入框类型
  YtInputType? inputType;
  //右侧图标
  Widget? shifxIcon;

  // 输入框描述
  String? labelText = '';
  //  错误提示
  String? errorText;
  // 输入框描述位置
  LabelPostion labelPostion;
// 左侧输入框描述样式
  TextStyle? labelTextStyle;
  // 是否为必填
  bool? isRequire;
  // 是否可输入
  bool? enabled;
  TextAlign textAlign;
  // 占位文字
  String? placeholderText;
  // 占位文字样式
  TextStyle? placeholderTextStyle;
  // 输入字体样式
  TextStyle? inputTextStyle;
  // 获取焦点时输入字体样式
  TextStyle? focusInputTextStyle;

  //边框
  InputBorder? border;
  // 如果不是文字，则自定义中间组件
  Widget? centerWidget;
  TextInputType? keyboardType;
  //最大字体书
  int? maxLength;
  // 框内背景颜色
  Color fillColor;
  // 边框圆角
  BorderRadiusGeometry? borderRadius;
  //输入框控制器
  final TextEditingController? controller;
  // 搜索控制器
  final YtSearchTextController? searchController;

  final VoidCallback? onPress;
  //输入变化回调
  final void Function(String)? onChanged;

  ///
  final void Function()? onEditingComplete;

  /// 清除按钮的回调 如果用户设置了该属性
  /// 如果返回值为true，表明用户想要拦截，则不会走默认的清除行为
  /// 如果返回值为false，表明用户不想要拦截，在执行了用户的行为之后，还会走默认的行为
  final YtOnTextClear? onTextClear;
  // 校验函数
  YtInputValidateFunction? validator;
  //错误提示信息行数
  int? errorMaxLines;
  //输入限制
  List<TextInputFormatter>? inputFormatters;
  //焦点
  FocusNode? focusNode;
  // 输入框左侧图标
  Widget? prefixBuilder;

  BoxConstraints? suffixIconConstraints;

  YtInput(
      {Key? key,
      this.titleWidth = 100,
      this.height = 41.0,
      this.maxLines = 1,
      this.errorMaxLines = 1,
      this.errorText,
      this.inputType,
      this.shifxIcon,
      this.labelText,
      this.textAlign = TextAlign.right,
      this.labelPostion = LabelPostion.left,
      this.labelTextStyle,
      this.isRequire = false,
      this.enabled = true,
      this.placeholderText = '',
      this.placeholderTextStyle,
      this.inputTextStyle,
      this.focusInputTextStyle,
      this.onTextClear,
      this.border,
      this.centerWidget,
      this.keyboardType = TextInputType.text,
      this.maxLength = 50,
      this.fillColor = Colors.transparent,
      this.borderRadius,
      this.focusNode,
      this.prefixBuilder,
      this.validator,
      this.controller,
      this.searchController,
      this.onChanged,
      this.onEditingComplete,
      this.inputFormatters,
      this.onPress,
      this.suffixIconConstraints})
      : super(key: key);

  @override
  State<YtInput> createState() => _YtInputState();
}

class _YtInputState extends State<YtInput> {
  bool pwShow = false;

  late FocusNode focusNode;
  TextEditingController? textEditingController;

  BoxBorder? border;

  YtSearchTextController? searchTextController;

  YtSearchTextController? tmpController;

  TextStyle? _contentTextStyle;

  @override
  initState() {
    super.initState();

    _contentTextStyle = widget.inputTextStyle;

    if (widget.searchController == null) {
      tmpController = YtSearchTextController()..isClearShow = false;
    }
    searchTextController = widget.searchController ?? tmpController;
    searchTextController!.addListener(() {
      if (mounted) {
        setState(() {});
      }
    });
    focusNode = widget.focusNode ?? FocusNode();
    focusNode.addListener(() {
      if (focusNode.hasFocus) {
        setState(() {
          _contentTextStyle = widget.focusInputTextStyle ?? _contentTextStyle;
        });
      } else {
        setState(() {
          _contentTextStyle = widget.inputTextStyle;
        });
      }
    });
    textEditingController = widget.controller ?? TextEditingController();
  }

  @override
  void dispose() {
    focusNode.dispose();
    searchTextController?.dispose();
    textEditingController?.dispose();
    super.dispose();
  }

  _changeHidePw() {
    setState(() {
      pwShow = !pwShow;
    });
  }

  Widget? getShifxIcon() {
    if (widget.inputType == YtInputType.password) {
      return GestureDetector(
        onTap: _changeHidePw,
        child: pwShow
            ? Image.asset('assets/images/icon_pw_show.png')
            : Image.asset('assets/images/icon_pw_hide.png'),
      );
    } else if (searchTextController!.isClearShow) {
      return GestureDetector(
        onTap: () {
          if (widget.onTextClear != null) {
            bool isIntercept = widget.onTextClear!();
            if (isIntercept) return;
          }
          focusNode?.requestFocus();
          textEditingController!.clear();
          setState(() {});
        },
        child: Visibility(
          visible: textEditingController!.text.isNotEmpty,
          child: const Padding(
              padding: EdgeInsets.symmetric(horizontal: 12.0),
              child: Icon(
                Icons.cancel,
                size: 20,
                color: Colors.black38,
              )),
        ),
      );
    } else {
      return widget.shifxIcon;
    }
  }

  @override
  Widget build(BuildContext context) {
    // ScreenUtil.init(context, designSize: const Size(375, 812), minTextAdapt: true);

    InputBorder? inputBorder = widget.border ?? defaultIBorder(context);

    Color? cursorColor = Theme.of(context).primaryColor;

    bool enableInteractiveSelection =
        widget.inputType == YtInputType.password ? false : true;

    double height = widget.height ?? 41;
    return InkWell(
        onTap: widget.onPress,
        child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
          Container(
            decoration: BoxDecoration(
                color: widget.fillColor, borderRadius: widget.borderRadius),
            child: widget.inputType == YtInputType.image //如果是图片类型，则自定义组件
                ? Container(
                    padding: EdgeInsets.only(
                        bottom: ScreenUtil().setHeight(6),
                        top: ScreenUtil().setHeight(8)),
                    decoration: const BoxDecoration(
                        border: Border(
                            bottom:
                                BorderSide(width: 0.5, color: Colors.black26))),
                    child: Row(
                      children: [
                        if (widget.isRequire == true)
                          Padding(
                            padding: EdgeInsets.only(left: 10.w, right: 4.w),
                            child: const Text(
                              '*',
                              style: TextStyle(
                                  color: Colors.red,
                                  fontWeight: FontWeight.bold),
                            ),
                          ),
                        Text(widget.labelText ?? '',
                            style: widget.labelTextStyle ??
                                Theme.of(context)
                                    .inputDecorationTheme
                                    .prefixStyle),
                        const Expanded(child: SizedBox()),
                        widget.centerWidget ?? const Text(''),
                        SizedBox(
                          width: ScreenUtil().setWidth(15),
                        ),
                        Visibility(
                            visible: widget.shifxIcon != null,
                            child: Padding(
                              padding: EdgeInsets.only(
                                  right: ScreenUtil().setWidth(15)),
                              child: widget.shifxIcon!,
                            ))
                      ],
                    ),
                  )
                : Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      if (widget.labelPostion == LabelPostion.top &&
                          widget.labelText != null)
                        getPrefixIcon()!,
                      TextFormField(
                        focusNode: focusNode,
                        maxLines: widget.maxLines,
                        textAlignVertical: TextAlignVertical.center,
                        textAlign: widget.textAlign,
                        cursorColor: cursorColor,
                        enableInteractiveSelection: enableInteractiveSelection,
                        inputFormatters:
                            widget.keyboardType == TextInputType.number
                                ? [
                                    FilteringTextInputFormatter.digitsOnly,
                                    ...?widget.inputFormatters
                                  ]
                                : widget.inputFormatters,
                        keyboardType: widget.keyboardType,
                        maxLength: widget.maxLength,
                        enabled: widget.enabled,
                        obscureText:
                            !pwShow && widget.inputType == YtInputType.password,
                        style: _contentTextStyle,
                        decoration: InputDecoration(
                          constraints: BoxConstraints(
                            minHeight: ScreenUtil().setHeight(height),
                          ),
                          contentPadding: const EdgeInsets.symmetric(
                              horizontal: 0, vertical: 0),
                          errorText: widget.errorText,
                          errorMaxLines: widget.errorMaxLines,
                          counterText: '',
                          hintText: widget.placeholderText,
                          hintStyle: widget.placeholderTextStyle,
                          prefixIcon: widget.labelPostion == LabelPostion.left
                              ? getPrefixIcon()
                              : null,
                          isCollapsed: true,
                          border: inputBorder,
                          enabledBorder: inputBorder,
                          suffixIcon: getShifxIcon(),
                          suffixIconConstraints: widget.suffixIconConstraints,
                        ),
                        controller: textEditingController,
                        onChanged: widget.onChanged,
                        onEditingComplete: widget.onEditingComplete,
                        validator: (value) {
                          if (widget.validator == null) {
                            return null;
                          } else {
                            var result = widget.validator!(value ?? '');

                            if (result != null && !result.succes) {
                              // 如果返回了错误信息，则展示
                              setState(() {
                                height = 62;
                              });
                              return result.errorMessqge;
                            } else {
                              return null;
                            }
                          }
                        },
                      ),
                    ],
                  ),
          ),
        ]));
  }

  isPrefixText() {
    if (widget.labelText == null && widget.isRequire != true) {
      return false;
    } else {
      return true;
    }
  }

  Widget? getPrefixIcon() {
    if (isPrefixText()) {
      return Row(
        mainAxisSize: MainAxisSize.min,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          if (widget.prefixBuilder != null) widget.prefixBuilder!,
          if (widget.isRequire == true)
            Padding(
              padding: EdgeInsets.only(left: 0.w, right: 4.w),
              child: const Text(
                '*',
                style:
                    TextStyle(color: Colors.red, fontWeight: FontWeight.bold),
              ),
            ),
          if (widget.labelText != null)
            Container(
              constraints: BoxConstraints(
                minWidth: widget.titleWidth,
              ),
              child: Text(widget.labelText ?? '',
                  style: widget.labelTextStyle ??
                      Theme.of(context).inputDecorationTheme.prefixStyle),
            )
        ],
      );
    } else {
      return widget.prefixBuilder;
    }
  }
}

enum YtInputType { text, image, password }

class YtInputValidateResult {
  bool succes;
  String errorMessqge;

  YtInputValidateResult({
    required this.succes,
    required this.errorMessqge,
  });
}

typedef YtInputValidateFunction = YtInputValidateResult? Function(String);

/// 右侧清除按钮 X 被点击的回调
typedef YtOnTextClear = bool Function();

InputBorder? defaultIBorder(BuildContext context) {
  return Theme.of(context).inputDecorationTheme.border;
}

enum LabelPostion { left, top }

/// 搜索框控制类，用于控制 清除 icon（x）、取消按钮的展示 隐藏
class YtSearchTextController extends ChangeNotifier {
  bool _isClearShow = true;

  bool get isClearShow => _isClearShow;

  /// 设置清除 icon 的展示隐藏
  set isClearShow(bool value) {
    _isClearShow = value;
    notifyListeners();
  }
}
